/**
 * API客户端配置模块
 * 
 * 功能说明：
 * - 配置axios基础设置，包括baseURL、超时时间、请求头等
 * - 实现请求/响应拦截器，自动处理认证token和错误
 * - 统一错误处理机制，提供友好的用户提示
 * - 自动token刷新机制，确保用户会话连续性
 * - 提供便捷的API请求方法封装
 * 
 * 核心特性：
 * - 自动认证：请求时自动注入Bearer token
 * - 智能刷新：401错误时自动刷新token并重试请求
 * - 错误处理：统一的HTTP状态码和网络错误处理
 * - 开发调试：开发环境下的详细请求/响应日志
 * - 安全清理：认证失败时自动清除本地状态并跳转登录
 * 
 * 使用场景：
 * - 所有前端API请求的统一入口
 * - 用户认证状态管理
 * - 网络错误和异常处理
 * - 开发调试和问题排查
 * - 用户体验优化
 */

import axios from 'axios'
import { message } from 'antd'

/**
 * API基础配置对象
 * 
 * 配置说明：
 * - baseURL: API基础路径，由Vite代理到后端服务器
 * - timeout: 请求超时时间，防止长时间等待
 * - headers: 默认请求头，指定内容类型为JSON
 */
const API_CONFIG = {
  baseURL: '',               // API基础路径，由Vite代理到后端
  timeout: 10000,           // 请求超时时间（毫秒）
  headers: {
    'Content-Type': 'application/json'
  }
}

/**
 * 创建axios实例
 * 
 * 使用自定义配置创建axios实例，确保所有请求都使用相同的配置
 */
const apiClient = axios.create(API_CONFIG)

/**
 * 请求拦截器
 * 
 * 功能说明：
 * - 自动添加认证token到请求头
 * - 记录请求日志（开发环境）
 * - 处理请求前的数据格式化
 * - 统一的请求预处理逻辑
 * 
 * 执行时机：在请求发送到服务器之前执行
 * 
 * @param {Object} config - axios请求配置对象
 * @returns {Object} 处理后的请求配置
 */
apiClient.interceptors.request.use(
  (config) => {
    // 从localStorage获取认证状态
    const authStorage = localStorage.getItem('auth-storage')
    console.log('🔍 检查localStorage:', authStorage ? '存在' : '不存在')
    
    if (authStorage) {
      try {
        // 解析认证状态数据
        const { state } = JSON.parse(authStorage)
        console.log('🔍 解析后的state:', state)
        
        // 提取访问token - 后端统一返回扁平结构
        const token = state?.token  // 只支持扁平结构：state.token
        console.log('🚩 当前token:', token ? '存在' : '不存在', token ? token.substring(0, 20) + '...' : '')
        
        if (token) {
          // 将token添加到请求头
          config.headers.Authorization = `Bearer ${token}`
          console.log('✅ Token已注入到请求头')
        } else {
          console.log('❌ Token不存在，无法注入')
        }
      } catch (error) {
        console.error('解析认证token失败:', error)
      }
    } else {
      console.log('❌ localStorage中没有auth-storage')
    }

    // 开发环境下记录详细的请求日志
    if (process.env.NODE_ENV === 'development') {
      console.log(`🚀 API请求: ${config.method?.toUpperCase()} ${config.url}`, {
        data: config.data,
        params: config.params,
        headers: config.headers
      })
    }

    return config
  },
  (error) => {
    console.error('请求拦截器错误:', error)
    return Promise.reject(error)
  }
)

/**
 * 响应拦截器
 * 
 * 功能说明：
 * - 统一响应数据格式处理
 * - 自动处理认证过期（401错误）
 * - 全局错误处理和用户提示
 * - 响应日志记录（开发环境）
 * 
 * 执行时机：在收到服务器响应后，返回给调用方之前执行
 * 
 * @param {Object} response - axios响应对象
 * @param {Object} error - axios错误对象
 * @returns {Object|Promise} 处理后的响应或拒绝的Promise
 */
apiClient.interceptors.response.use(
  (response) => {
    // 开发环境下记录响应日志
    if (process.env.NODE_ENV === 'development') {
      console.log(`✅ API响应: ${response.config.method?.toUpperCase()} ${response.config.url}`, {
        status: response.status,
        data: response.data
      })
    }

    return response
  },
  async (error) => {
    const { response, config } = error

    // 开发环境下记录错误日志
    if (process.env.NODE_ENV === 'development') {
      console.error(`❌ API错误: ${config?.method?.toUpperCase()} ${config?.url}`, {
        status: response?.status,
        message: response?.data?.message,
        error: error.message
      })
    }

    // 根据HTTP状态码进行不同的错误处理
    if (response) {
      switch (response.status) {
        case 401:
          // 认证失败，尝试刷新token
          return handleUnauthorized(error)
        
        case 403:
          message.error('没有权限访问此资源')
          break
        
        case 404:
          message.error('请求的资源不存在')
          break
        
        case 422:
          // 表单验证错误，由具体组件处理，不显示全局提示
          break
        
        case 429:
          message.error('请求过于频繁，请稍后重试')
          break
        
        case 500:
          message.error('服务器内部错误，请稍后重试')
          break
        
        default:
          // 其他状态码，显示服务器返回的错误消息或默认消息
          if (response.data?.message) {
            message.error(response.data.message)
          } else {
            message.error(`请求失败 (${response.status})`)
          }
      }
    } else {
      // 网络错误或超时处理
      if (error.code === 'ECONNABORTED') {
        message.error('请求超时，请检查网络连接')
      } else if (error.message === 'Network Error') {
        message.error('网络连接失败，请检查网络')
      } else {
        message.error('网络错误，请稍后重试')
      }
    }

    return Promise.reject(error)
  }
)

/**
 * 处理401未授权错误
 * 
 * 功能说明：
 * - 检测到401错误时自动尝试刷新token
 * - 刷新成功后重试原请求
 * - 刷新失败时清除认证状态并跳转登录页
 * - 防止无限循环刷新
 * 
 * 执行流程：
 * 1. 检查是否为刷新token请求（避免无限循环）
 * 2. 从localStorage获取刷新token
 * 3. 调用后端刷新token API
 * 4. 更新本地存储的token
 * 5. 重试原请求或清除认证状态
 * 
 * @param {Object} error - axios错误对象
 * @returns {Promise} 重试请求或拒绝的Promise
 */
async function handleUnauthorized(error) {
  const { config } = error
  
  // 避免无限循环，如果是刷新token的请求失败，直接拒绝
  if (config.url.includes('/auth/refresh')) {
    clearAuthAndRedirect()
    return Promise.reject(error)
  }

  try {
    // 获取刷新token
    const authStorage = localStorage.getItem('auth-storage')
    if (!authStorage) {
      clearAuthAndRedirect()
      return Promise.reject(error)
    }

    const { state } = JSON.parse(authStorage)
    if (!state?.refreshToken) {
      clearAuthAndRedirect()
      return Promise.reject(error)
    }

    // 调用刷新token API - 使用apiClient保持配置一致
    // 注意：后端refresh接口期望refresh_token字段名
    const refreshResponse = await apiClient.post('/api/auth/refresh', {
      refresh_token: state.refreshToken
    })

    // 检查是否有有效的access_token（后端统一返回扁平结构）
    if (refreshResponse.data.access_token) {
      // 更新本地存储的token - 使用扁平结构
      const newAuthState = {
        ...state,
        token: refreshResponse.data.access_token,
        refreshToken: refreshResponse.data.refresh_token
      }
      
      localStorage.setItem('auth-storage', JSON.stringify({
        state: newAuthState,
        version: 0
      }))

      // 更新原请求的认证头
      config.headers.Authorization = `Bearer ${refreshResponse.data.access_token}`
      
      // 重新发送原请求
      return apiClient(config)
    } else {
      clearAuthAndRedirect()
      return Promise.reject(error)
    }
  } catch (refreshError) {
    console.error('Token刷新失败:', refreshError)
    clearAuthAndRedirect()
    return Promise.reject(error)
  }
}

/**
 * 清除认证状态并重定向到登录页
 * 
 * 功能说明：
 * - 清除localStorage中的认证数据
 * - 如果当前不在登录页，则跳转到登录页
 * - 确保用户重新登录获取新的认证状态
 * 
 * 使用场景：
 * - Token刷新失败时
 * - 用户主动登出时
 * - 认证状态异常时
 */
function clearAuthAndRedirect() {
  // 清除本地存储的认证数据
  localStorage.removeItem('auth-storage')
  
  // 如果当前不在登录页，则跳转到登录页
  if (window.location.pathname !== '/login') {
    window.location.href = '/login'
  }
}

/**
 * API请求方法封装
 * 
 * 功能说明：
 * - 提供统一的请求方法，简化组件中的API调用
 * - 支持GET、POST、PUT、PATCH、DELETE、UPLOAD等HTTP方法
 * - 自动应用axios实例的配置和拦截器
 * - 提供类型安全的参数传递
 * 
 * 使用示例：
 * - api.get('/users', { page: 1, limit: 10 })
 * - api.post('/auth/login', { email, password })
 * - api.put('/products/123', { name, price })
 * - api.delete('/products/123')
 * - api.upload('/upload', formData, onProgress)
 */
export const api = {
  /**
   * GET请求方法
   * 
   * 用于获取数据，参数通过URL查询字符串传递
   * 
   * @param {string} url - 请求URL路径
   * @param {Object} params - 查询参数对象
   * @param {Object} config - 额外的axios配置
   * @returns {Promise} 响应数据Promise
   */
  get: (url, params = {}, config = {}) => {
    return apiClient.get(url, { params, ...config })
  },

  /**
   * POST请求方法
   * 
   * 用于创建新资源，数据通过请求体传递
   * 
   * @param {string} url - 请求URL路径
   * @param {Object} data - 请求体数据
   * @param {Object} config - 额外的axios配置
   * @returns {Promise} 响应数据Promise
   */
  post: (url, data = {}, config = {}) => {
    return apiClient.post(url, data, config)
  },

  /**
   * PUT请求方法
   * 
   * 用于完整更新资源，数据通过请求体传递
   * 
   * @param {string} url - 请求URL路径
   * @param {Object} data - 请求体数据
   * @param {Object} config - 额外的axios配置
   * @returns {Promise} 响应数据Promise
   */
  put: (url, data = {}, config = {}) => {
    return apiClient.put(url, data, config)
  },

  /**
   * PATCH请求方法
   * 
   * 用于部分更新资源，数据通过请求体传递
   * 
   * @param {string} url - 请求URL路径
   * @param {Object} data - 请求体数据
   * @param {Object} config - 额外的axios配置
   * @returns {Promise} 响应数据Promise
   */
  patch: (url, data = {}, config = {}) => {
    return apiClient.patch(url, data, config)
  },

  /**
   * DELETE请求方法
   * 
   * 用于删除资源
   * 
   * @param {string} url - 请求URL路径
   * @param {Object} config - 额外的axios配置
   * @returns {Promise} 响应数据Promise
   */
  delete: (url, config = {}) => {
    return apiClient.delete(url, config)
  },

  /**
   * 文件上传方法
   * 
   * 用于上传文件，自动设置multipart/form-data内容类型
   * 
   * @param {string} url - 上传URL路径
   * @param {FormData} formData - 文件数据FormData对象
   * @param {Function} onProgress - 上传进度回调函数
   * @returns {Promise} 响应数据Promise
   */
  upload: (url, formData, onProgress) => {
    return apiClient.post(url, formData, {
      headers: {
        'Content-Type': 'multipart/form-data'
      },
      onUploadProgress: onProgress
    })
  }
}

/**
 * 交易相关API方法
 * 
 * 功能说明：
 * - 提供交易相关的便捷API调用方法
 * - 自动处理认证和错误
 * - 简化组件中的交易操作
 */

/**
 * 获取当前用户所有交易（买入和卖出）
 * 
 * @returns {Promise} 交易列表数据
 */
export function getMyTrades() {
  return apiClient.get('/api/trades')
}

/**
 * 创建新交易（购买商品）
 * 
 * @param {Object} data - 交易数据
 * @param {number} data.product_id - 商品ID
 * @param {string} data.payment_method - 支付方式
 * @param {string} data.remark - 备注信息
 * @returns {Promise} 创建结果
 */
export function createTrade(data) {
  return apiClient.post('/api/trades', data)
}

/**
 * 获取交易详情
 * 
 * @param {number|string} id - 交易ID
 * @returns {Promise} 交易详情数据
 */
export function getTradeById(id) {
  return apiClient.get(`/api/trades/${id}`)
}

/**
 * 更新交易状态
 * 
 * @param {number|string} id - 交易ID
 * @param {Object} data - 状态数据
 * @param {string} data.status - 新状态
 * @param {string} data.reason - 状态变更原因
 * @returns {Promise} 更新结果
 */
export function updateTradeStatus(id, data) {
  return apiClient.put(`/api/trades/${id}/status`, data)
}

/**
 * 取消交易
 * 
 * @param {number|string} id - 交易ID
 * @param {Object} data - 取消原因
 * @param {string} data.reason - 取消原因
 * @returns {Promise} 取消结果
 */
export function cancelTrade(id, data) {
  return apiClient.put(`/api/trades/${id}/cancel`, data)
}

/**
 * 商品相关API方法
 * 
 * 功能说明：
 * - 提供商品相关的便捷API调用方法
 * - 自动处理用户ID参数
 * - 简化商品管理操作
 */

/**
 * 获取我发布的商品
 * 
 * @param {Object} params - 查询参数（如分页）
 * @returns {Promise} 商品列表数据
 */
export function getMyProducts(params = {}) {
  // 自动补全 user_id 参数，并转换为 seller_id（后端使用 seller_id）
  const authStorage = localStorage.getItem('auth-storage')
  let userId = params.user_id
  if (!userId && authStorage) {
    try {
      const { state } = JSON.parse(authStorage)
      userId = state?.user?.id
    } catch {}
  }
  return apiClient.get('/api/products', { ...params, seller_id: userId })
}

/**
 * 获取我收到的评价
 * 
 * @param {Object} params - 查询参数（如分页）
 * @returns {Promise} 评价列表数据
 */
export function getMyEvaluations(params = {}) {
  return apiClient.get('/api/reviews/my-reviews/', params)
}

/**
 * 删除商品
 * 
 * @param {number|string} id - 商品ID
 * @returns {Promise} 删除结果
 */
export function deleteProduct(id) {
  return apiClient.delete(`/api/products/${id}`)
}

/**
 * 钱包相关API方法
 * 
 * 功能说明：
 * - 提供钱包相关的便捷API调用方法
 * - 简化钱包操作
 */

/**
 * 获取钱包余额
 * 
 * @returns {Promise} 钱包余额数据
 */
export function getWalletBalance() {
  return apiClient.get('/api/wallet/balance')
}

/**
 * 钱包充值
 * 
 * @param {Object} data - 充值数据
 * @param {number} data.amount - 充值金额
 * @returns {Promise} 充值结果
 */
export function rechargeWallet(data) {
  return apiClient.post('/api/wallet/recharge', data)
}

// 导出axios实例作为默认导出
export default apiClient 